import React, { useState, useEffect, useCallback } from 'react'
import { View } from 'react-native'
import EStyleSheet from 'react-native-extended-stylesheet'
import BleManager from '@UTILS/BleManager'
import Permissions from '@UTILS/Permissions'
import { State, Device } from 'react-native-ble-plx'
import BluetoothStateManager from 'react-native-bluetooth-state-manager'
import { BleConnectivityStatus, DeviceState } from '@CONSTANTS/BleConstants'
import { isIOS, openAppStore } from '@UTILS/Common'
import Images from '@IMAGE'
import AppUpdatePopup from '@COMPONENTS/Popup/AppUpdatePopup'
import { useAppSelector, useAppDispatch } from '@REDUX/store'
import Toast from '@COMPONENTS/Toast'
import { useNavigation } from '@react-navigation/native'
import { actions } from '@REDUX/reducer/user'
import Api from '@API'
import Storage, { StorageKey } from '@UTILS/Storage'
import NoStart from './NoStart'
import Connected from './Connected'
import ErrorState from './ErrorState'

const minTreatmentTimeInSeconds = 1800
const getConnectCount = async () => {
  const connectCount = await Storage.get(StorageKey.connectCount)
  return connectCount || 0
}

const Disconnected = [BleConnectivityStatus.SearchingTimedOut, BleConnectivityStatus.ConnectionTimedOut]
const Error = [BleConnectivityStatus.AuthenticationFailed, BleConnectivityStatus.ConnectionTimedOut]
type Status = BleConnectivityStatus | 'exhausted'

const Home: React.FC = () => {
  const { state: deviceState, treatmentTimeLeftInSeconds } = useAppSelector((state) => state.home.deviceData)
  const user = useAppSelector((state) => state.user)
  const { DeviceUUID } = user.user
  const appUpdatInfo = user.appUpdatInfo || {}
  const { ForceUpdate, ...updateInfo } = appUpdatInfo
  const [showAppUpdate, setAppUpdate] = useState(false)
  const dispatch = useAppDispatch()
  console.log('DeviceUUID333', DeviceUUID)
  const navigation = useNavigation()
  const [bleState, setBleState] = useState<State>(State.PoweredOff)
  const [status, setStatus] = useState<Status>(BleConnectivityStatus.Disconnected)
  const isNoStart = bleState === State.PoweredOn && [BleConnectivityStatus.Searching, BleConnectivityStatus.Disconnected].includes(status)
  const isError = [State.PoweredOff].includes(bleState) || Error.includes(status)
  console.log('index-page', deviceState, bleState, status, isNoStart, isError)

  const connectSuccess = useCallback(
    async (deviceInfo:Device) => {
      const number = await getConnectCount()
      Storage.set(StorageKey.connectCount, number + 1)
      Api.addActivity({
        DeviceId: deviceInfo.id,
        ActivityType: 'Connect',
        Intensity: 0,
        DeviceResponse: {},
        DeviceMinutes: 0,
      })
      const deviceId = deviceInfo?.id
      if (deviceId && DeviceUUID !== deviceId) {
        Api.devicePair({ DeviceUUID: deviceInfo?.id })
          .then((res) => {
            console.log('devicePair', res)
            dispatch(actions.updateDeviceUUID(deviceId))
          })
          .catch((e) => {
            Toast.error(e?.message || e)
          })
      }
    },
    [DeviceUUID, dispatch],
  )

  const connectDevice = useCallback(async (bleStatus: State, newDevice?:boolean) => {
    switch (bleStatus) {
      case State.PoweredOn: {
        console.log('grantedgrantedgranted')
        // android 需要额外权限
        const p = await Permissions.allPrerequisitesOK()
        console.log('grantedgrantedgranted22')

        if (!isIOS && !p) {
          const granted = await Permissions.requestBluPermission()
          console.log('grantedgrantedgranted', granted)
          if (!granted) {
            console.log('State.Unauthorized', State.Unauthorized)
          }
          BleManager.connect(newDevice ? null : DeviceUUID, async (error1, deviceInfo) => {
            console.log('infoinfoinfo22', error1, deviceInfo)
            if (deviceInfo) {
              connectSuccess(deviceInfo)
            }
          })
        } else {
          BleManager.connect(newDevice ? null : DeviceUUID, async (error1, deviceInfo) => {
            if (deviceInfo) {
              connectSuccess(deviceInfo)
            }
          })
        }

        break
      }
      case State.PoweredOff: {
        if (isIOS) {
          BluetoothStateManager.openSettings()
        } else {
          const p = await Permissions.allPrerequisitesOK()
          if (p) {
            BluetoothStateManager.enable()
          } else {
            const granted = await Permissions.requestBluPermission()
            if (!granted) {
              Toast.info('需要开启权限使用')
            } else {
              BluetoothStateManager.enable()
            }
          }
        }
        break
      }
      case State.Unauthorized: {
        break
      }
      default: {
        break
      }
    }
  }, [DeviceUUID, connectSuccess])

  const confirmUpdate = useCallback(() => {
    setAppUpdate(false)
    openAppStore()
  }, [setAppUpdate])

  useEffect(() => {
    if (bleState === State.PoweredOn) {
      connectDevice(bleState)
    }
  }, [bleState, connectDevice])

  useEffect(() => {
    BleManager.init()
    const sub = BleManager.onStateChange(async (newState) => {
      const p = await Permissions.isEnabledBlu()
      if (isIOS && !p) {
        console.log('State.Unauthorized')
        return
      }
      Api.addActivity({
        DeviceId: '',
        ActivityType: newState,
        Intensity: 0,
        DeviceResponse: {},
        DeviceMinutes: 0,
      })
      setBleState(newState)
    }, true)
    BleManager.addPeripheralConnectionStateListener(async (bleStatus, deviceInfo) => {
      console.log('bleStatus', bleStatus)
      if ([BleConnectivityStatus.Searching, BleConnectivityStatus.Connecting].includes(bleStatus)) {
        setStatus(BleConnectivityStatus.Searching)
        return
      }
      if (Disconnected.includes(bleStatus)) {
        setStatus(BleConnectivityStatus.ConnectionTimedOut)
        return
      }
      if (bleStatus === BleConnectivityStatus.Disconnected) {
        return
      }
      if (bleStatus === BleConnectivityStatus.Searched) {
        Api.deviceRegister({ DeviceUUID: deviceInfo?.id })
          .catch((e) => {
            Toast.error(e?.message || e)
          })
      }
      setStatus(bleStatus)
    })
    return () => {
      BleManager.remove(sub)
      BleManager.stopDeviceScan()
      BleManager.removeAllPeripheralConnectionStateListener()
    }
  }, [])

  useEffect(() => {
    if ([DeviceState.Shutdown, DeviceState.Unknown].includes(deviceState)) {
      setStatus(BleConnectivityStatus.Disconnected)
      navigation.setOptions({
        headerRight: '',
      })
    }
  }, [deviceState, setStatus, navigation])

  useEffect(() => {
    if ([DeviceState.Treatment, DeviceState.Pause].includes(deviceState) && treatmentTimeLeftInSeconds < minTreatmentTimeInSeconds) {
      setStatus('exhausted')
    }
  }, [treatmentTimeLeftInSeconds, deviceState, setStatus])

   useEffect(() => {
    if (ForceUpdate) setAppUpdate(ForceUpdate)
  }, [ForceUpdate])

  return (
    <View style={styles.page}>
      {status === BleConnectivityStatus.Connected && <Connected />}
      {isNoStart && <NoStart status={status} connectDevice={connectDevice} />}
      {isError && <ErrorState bleState={bleState} bleConnectivityStatus={status} connectDevice={connectDevice} />}
      {/* @ts-ignore */}
      {!!updateInfo && showAppUpdate && <AppUpdatePopup updateInfo={appUpdatInfo} onConfirm={confirmUpdate} />}
    </View>
  )
}

export default Home

const styles = EStyleSheet.create({
  page: {
    flex: 1,
    backgroundColor: '$bgColor',
    justifyContent: 'center',
    alignItems: 'center',
  },
})
